/**
 * @desc: 找家纺ERP项目主要内容入口文件,包含权限管理
 * @author: Elvis
 */

import React, { useState, useEffect, Suspense, useRef, useCallback } from "react";
import { ConfigProvider, notification, Modal } from "antd";
import { useNavigate, useLocation, useOutlet } from "react-router-dom";
import PageLoading from "@/components/PageLoading";
import AsideMenuNew from "@/components/GlobalLayout/AsideMenuNew";
import Header from "@/components/GlobalLayout/Header";
import MessageConfirm from "@/components/GlobalLayout/MessageConfirm";
import NotAuth from "@/pages/403.jsx";
import { findIndex } from "lodash";
import { getToken, removeAll } from "@/utils/authority";
import { listenUserMsg } from "@/services/user";
import zhCN from "antd/es/locale/zh_CN";
import moment from "moment";
import "@/assets/css/global_new.less";
import "@/assets/css/new.less";
import "@/views/assets/global.less";
import "moment/dist/locale/zh-cn";
import styles from "./MainLayout.module.less";
moment.locale("zh-cn");

//获取路由名称
const getRouteName = (arr, path) => {
	if(path == '/home') {
		return '首页';
	}
	for(let i in arr) {
		for(let k in arr[i].children) {
			for(let j in arr[i].children[k].children) {
				const obj = arr[i].children[k].children[j];
				if(obj.path == path) {
					return obj.name;
				}
			}
		}
	}
	return '';
};

//渲染子页面
const ViewPage = props => {
	const outlet = useOutlet();
	return props.render(<Suspense fallback={<PageLoading />}>{outlet}</Suspense>);
};

const BasicLayout = ({ initTab, menuData }) => {
	const navigate = useNavigate();

	const location = useLocation();

	//当前活动的key
	const [activeKey, setActiveKey] = useState();

	//已经加载的路由组件
	const [tabList, setTabList] = useState(initTab);

	const path = location.pathname;

	const cacheElements = useRef({}).current;

	//缓存的锁定列信息
	const [cacheTab, setCacheTab] = useState(initTab);

	//页面展示最多的标签数 - 1，作为下标，其他放到下拉框里
	const maxCount = 9;

	useEffect(() => {
		loadScriptsFunc();
		listenUser();
	}, []);

	//需额外加载的脚本， 其它可配置文件中添加
	const loadScriptsFunc = () => {
		const scriptUrlList = [
			{
				url: "https://g.alicdn.com/sj/securesdk/0.0.3/securesdk_v2.js",
				attr: { id: "J_secure_sdk_v2", "data-appkey": 23416550 }
			}
		];
		scriptUrlList.map(item => {
			const script = document.createElement("script");
			script.setAttribute("src", item.url);
			if (item.attr && typeof item.attr == "object") {
				const arr = Object.keys(item.attr);
				arr.map(props => {
					script.setAttribute(props, item.attr[props]);
				});
			}
			script.setAttribute("type", "text/javascript");
			script.setAttribute("charset", "utf-8");
			document.body.appendChild(script);
		});
	};

	//监听token有效与否
	function listenUser() {
		let timer = setInterval(async () => {
			if (getToken()) {
				const res = listenUserMsg();
				if (res.success) {
					if (!res.data) {
						//用户信息有效，去查询菜单数据
						notification.info({
							message: `温馨提示`,
							description: "登录信息已失效，请重新登录",
							duration: null
						});
						removeAll();
						clearInterval(timer);
						timer = null;
						if (location.pathname !== "/user/login") {
							navigate("/user/login", { replace: true });
						}
					}
				}
			}
		}, 600000);
	}

	useEffect(() => {
		if (path == "/") {
			navigate("/home");
			return;
		}
		Modal.destroyAll();
		handlePathChange(path);
	}, [path]);

	//增加tab项
	const addTab = useCallback(
		val => {
			const existItem = tabList.find(it => it.key === val);
			if (!existItem) {
				const name = getRouteName(menuData, val);
				if (!name) {
					navigate("/403");
					return;
				}
				//如果已经超出最大展示数，直接放在最后一位展示位
				const obj = {
					key: val,
					tab: name,
					lock: findIndex(cacheTab, ['key', val]) > -1 ? true : false,
				};
				if (tabList.length > maxCount) {
					if (tabList.length > 14) {
						delete cacheElements[tabList[tabList.length - 1].key];
						tabList.pop();
					}
					tabList.splice(maxCount, 0, obj);
					setTabList(tabList);
				} else {
					setTabList([...tabList, obj]);
				}
			}
			setActiveKey(val);
		},
		[tabList]
	);

	//路由路径发生变更
	const handlePathChange = useCallback(
		path => {
			addTab(path);
		},
		[addTab]
	);

	//点击切换tab
	const changeTab = useCallback(
		val => {
			const index = findIndex(tabList, ["key", val]);
			if (index > maxCount) {
				const obj = tabList[maxCount];
				const obj1 = tabList[index];
				tabList[index] = obj;
				tabList[maxCount] = obj1;
				setTabList(tabList);
			}
			setActiveKey(val);
			navigate(val);
		},
		[tabList, navigate]
	);

	//移除tab,type == 1，移除全部（除首页外）， type == 2，移除单个
	const removeTab = useCallback(
		(type, val) => {
			if (type == 1) {
				for (let i in cacheElements) {
					if (i != "/home") {
						delete cacheElements[i];
					}
				}
				setTabList([{ key: "/home", tab: "首页", lock: true }]);
				//在首页时不会显示其他的tab
				changeTab("/home");
			} else {
				delete cacheElements[val];
				const newItems = tabList.filter(d => d.key !== val);
				setTabList(newItems);
				if (val == window.location.hash.replace("#", "")) {
					const index = findIndex(tabList, ["key", val]);
					changeTab(tabList[index - 1].key);
				}
			}
		},
		[tabList, changeTab]
	);

	//渲染页面
	const renderView = useCallback(
		routeElement => {
			if (!activeKey) {
				return;
			}
			if (!cacheElements[activeKey]) {
				if (getRouteName(menuData, activeKey)) {
					cacheElements[activeKey] = <div>{routeElement}</div>;
				} else {
					cacheElements[activeKey] = (
						<div>
							<NotAuth />
						</div>
					);
				}
			}
			return Object.keys(cacheElements).map(key => {
				const element = cacheElements[key];
				if (key === activeKey) {
					return React.cloneElement(element, {
						key: key,
						style: {
							display: "block"
						},
						className: "views-layout"
					});
				} else {
					return React.cloneElement(element, {
						key: key,
						style: {
							display: "none"
						},
						className: "views-layout"
					});
				}
			});
		},
		[cacheElements, activeKey]
	);

	//顶部栏相关props
	const HeaderProps = {
		isNew: true,
		cacheTab,
		setCacheTab,
		tabList,
		activeKey,
		setTabList,
		onClick(val) {
			if (val == "closeAll") {
				removeTab(1);
			} else {
				changeTab(val);
			}
		},
		onCancel(val) {
			removeTab(2, val);
		}
	};

	return (
		<ConfigProvider locale={zhCN} componentSize="small">
			<div className={styles.wrap}>
				<aside className={styles.aside}>
					<AsideMenuNew menuData={menuData} />
				</aside>
				<section className={styles.section}>
					<header className={styles.header}>
						<Header {...HeaderProps} />
					</header>
					<section className="sectionContent" id="sectionContent">
						<ViewPage render={renderView}></ViewPage>
					</section>
				</section>
			</div>
			<MessageConfirm />
		</ConfigProvider>
	);
};

export default BasicLayout;
